package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.exception.BizException;
import com.gap.cache.redis.RedisCache;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.shared.constant.*;
import com.mingqijia.gassafety.shared.dto.LogVO;
import com.mingqijia.gassafety.shared.dto.TaskDetailParamDTO;
import com.mingqijia.gassafety.shared.dto.TaskDetailRespDTO;
import com.mingqijia.gassafety.shared.user.UserBackend;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageColumns;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import com.mingqijia.gassafety.webserver.request.*;
import com.mingqijia.gassafety.webserver.response.*;
import com.mingqijia.gassafety.webserver.service.CompanyService;
import com.mingqijia.gassafety.webserver.service.FieldTemplateService;
import com.mingqijia.gassafety.webserver.service.ServicePkgRecordService;
import com.mingqijia.gassafety.webserver.service.WarnStrategyService;
import com.mingqijia.gassafety.webserver.utils.LogRecordAspect;
import com.mingqijia.gassafety.webserver.utils.LogUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ConvertingCursor;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static com.mingqijia.gassafety.shared.constant.Constants.ORG_MAP_SUBSCODE;

/**
 * <p>
 * 报警策略 服务实现类
 * </p>
 *
 * @author zhangfei
 * @since 2022-02-25
 */
@Service
@Slf4j
public class WarnStrategyServiceImpl extends ServiceImpl<WarnStrategyMapper, WarnStrategy> implements WarnStrategyService {

    @Autowired
    private WarnStrategyMapper warnStrategyMapper;
    @Autowired
    private WarnStrategyExtMapper warnStrategyExtMapper;
    public static final String split = ";";
    @Autowired
    RedisCache redisCache;
    public static final String format = "yyyy-MM-dd HH:mm:ss";
    @Autowired
    WarningRecordMapper warningRecordMapper;
    @Autowired
    EquipmentServiceImpl equipmentService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    VccAuthoritiesProvider provider;
    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    FieldTemplateService fieldTemplateService;

    @Autowired
    WarnStrategyCheckMapper warnStrategyCheckMapper;

    @Autowired
    BusinessNoticeMapper businessNoticeMapper;


    @Autowired
    FieldTemplateMapper fieldTemplateMapper;

    @Autowired
    InformRecordMapper informRecordMapper;

    @Autowired
    private ServicePkgRecordService servicePkgRecordService;

    @Autowired
    SendMessageService sendMessageService;

    @Resource
    CompanyService companyService;

    @Autowired
    ConfigureHolder holder;

    private static final String phoneRegex = "^(1[3-9])\\d{9}$";
    private static final String landlineRegex = "\\d{3,4}[-]\\d{7,8}";

    /**
     * 新增
     * source：0开启 1关闭
     *
     * @param request
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object saveWarnStrategy(SaveWarnStrategyRequest request, int source) {
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("checkOpen", 1);
        String spId = ApplicationUtils.getWorkingSpId();
        //获取spId对应的是否开启状态
        List<BusinessNotice> businessNotices = getBusinessNotices(spId);
        Integer checkSwitch = 1;
        if (!CollectionUtil.isEmpty(businessNotices)) {
            BusinessNotice businessNotice = businessNotices.get(0);
            if ("ON".equals(businessNotice.getParamValue())) checkSwitch = 0;
        }
        if (source == 1) spId = request.getSpId();
        //校验
        WarnStrategy warn = new WarnStrategy();
        if (request.getStrategyObj() != 0 &&
                !StringUtils.isEmpty(request.getStrategyObjValues()) && source != 1) {
            warn.setStrategyObjValues(request.getStrategyObjValues() + split);
            request.setStrategyObjValues(request.getStrategyObjValues() + split);
        }

        if (!StringUtils.isEmpty(request.getHighWxPhones()) &&
                !request.getHighWxPhones().contains(split)) {
            request.setHighWxPhones(request.getHighWxPhones() + split);
        }
        if (!StringUtils.isEmpty(request.getLowWxPhones()) &&
                !request.getLowWxPhones().contains(split)) {
            request.setLowWxPhones(request.getLowWxPhones() + split);
        }
        List<WarnStrategy> warnStrategies = queryStrategy(request, spId, null);
        List<WarnStrategy> checkStrategies = warnStrategyMapper.checkStrategies(spId);
        if (!CollectionUtil.isEmpty(warnStrategies) || (request.getStrategyObj() == 0
                && !CollectionUtil.isEmpty(checkStrategies)))
            throw new BizException("当前客户已绑定报警规则");
        checkRule(request);

        if (source != 0 || checkSwitch == 1) {
            List<WarnStrategyExtRequest> extDatas = request.getExtData();
            BeanUtils.copyProperties(request, warn);
            warn.setSpId(spId);
            warn.setIsDisabled(request.getSaveAndEnable());
            warnStrategyMapper.insert(warn);
            if (!StringUtils.isEmpty(warn.getHighReport())
                    || !StringUtils.isEmpty(warn.getLowReport())) {
                saveBatchExts(extDatas, warn, spId);
            }
        } else if (source == 0 && checkSwitch == 0) {
            //新增审核数据
            insertCheck(request, spId);
            resMap.put("checkOpen", 0);
        }
        //企业级操作日志
        LogVO vo = new LogVO();
        StringBuilder stringBuilder = new StringBuilder();
//        String detail = LogUtil.addOrDeleteEntity(warn, WarnStrategy.class);
        stringBuilder.append("【规则名称：" + request.getRuleName() + "】成功");
        vo.setDetail(stringBuilder.toString());
        LogRecordAspect.threadLocal.set(vo);
        return resMap;
    }

    /**
     * 编辑策略
     *
     * @param request
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object editWarnStrategy(SaveWarnStrategyRequest request, int source) {
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("checkOpen", 1);
        String spId = ApplicationUtils.getWorkingSpId();
        //获取spId对应的是否开启状态
        List<BusinessNotice> businessNotices = getBusinessNotices(spId);
        Integer checkSwitch = 1;
        if (!CollectionUtil.isEmpty(businessNotices)) {
            BusinessNotice businessNotice = businessNotices.get(0);
            if ("ON".equals(businessNotice.getParamValue())) checkSwitch = 0;
        }
        if (source == 1) spId = request.getSpId();
        if (request.getId() == null) throw new BizException("id必传字段");
        WarnStrategy warn = warnStrategyMapper.selectWarnStrategyById(request.getId());
        log.info("editWarnStrategy-warn:{}", com.alibaba.fastjson.JSONObject.toJSONString(warn));
        if (warn == null) throw new BizException("数据不存在或已失效");
        if (warn.getIsDisabled() == 0) {
            //校验规则是否在使用
            int count = warningRecordMapper.selectWarnStrategyUse(request.getId());
            if (count > 0) throw new BizException("执行中的策略不可编辑");
        }

        if (request.getStrategyObj() != 0 &&
                !StringUtils.isEmpty(request.getStrategyObjValues()) && source != 1) {
            char lastChar = request.getStrategyObjValues().charAt(request.getStrategyObjValues().length() - 1);
            if (lastChar == ';') {
                request.setStrategyObjValues(request.getStrategyObjValues());
            } else {
                request.setStrategyObjValues(request.getStrategyObjValues() + split);
            }
        }

        if (!StringUtils.isEmpty(request.getHighWxPhones()) &&
                !request.getHighWxPhones().contains(split)) {
            request.setHighWxPhones(request.getHighWxPhones() + split);
        }
        if (!StringUtils.isEmpty(request.getLowWxPhones()) &&
                !request.getLowWxPhones().contains(split)) {
            request.setLowWxPhones(request.getLowWxPhones() + split);
        }

        List<WarnStrategy> warnStrategies = queryStrategy(request, spId, request.getId());
        if (!CollectionUtil.isEmpty(warnStrategies))
            throw new BizException("客户已绑定报警规则");
        List<WarnStrategyExtRequest> extData = request.getExtData();
        checkHighLowType(request);
        checkRule(request);
        if (source != 0 || checkSwitch == 1) {
            WarnStrategy warnStrategy = new WarnStrategy();
            BeanUtils.copyProperties(request, warnStrategy);
            warnStrategy.setSpId(spId);
            warnStrategy.setIsDisabled(request.getSaveAndEnable());
            if (StringUtils.isEmpty(request.getStrategyObjValues())) {
                warnStrategy.setStrategyObjValues("");
            }
            if (StringUtils.isEmpty(warnStrategy.getLowReport())) {
                warnStrategy.setLowReport("");
                warnStrategy.setLowReportInterval(0 + "");
                warnStrategy.setLowType(-1);
                warnStrategy.setLowSendInterval(0 + "");
            }
            if (StringUtils.isEmpty(warnStrategy.getHighReport())) {
                warnStrategy.setHighReport("");
                warnStrategy.setHighReportInterval(0 + "");
                warnStrategy.setHighType(-1);
                warnStrategy.setHighSendInterval(0 + "");
            }
            if (warnStrategy.getHighWxPhones() == null) warnStrategy.setHighWxPhones("");
            if (warnStrategy.getLowWxPhones() == null) warnStrategy.setLowWxPhones("");
            if (StringUtils.isEmpty(warnStrategy.getHighReportInterval())) warnStrategy.setHighReportInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getHighSendInterval())) warnStrategy.setHighSendInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getHighWxInterval())) warnStrategy.setHighWxInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getHighCallInterval())) warnStrategy.setHighCallInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getLowReportInterval())) warnStrategy.setLowReportInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getLowSendInterval())) warnStrategy.setLowSendInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getLowWxInterval())) warnStrategy.setLowWxInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getLowCallInterval())) warnStrategy.setLowCallInterval(0 + "");
            if (StringUtils.isEmpty(warnStrategy.getHighSmsMsgCode())) warnStrategy.setHighSmsMsgCode("");
            if (StringUtils.isEmpty(warnStrategy.getHighWxMsgCode())) warnStrategy.setHighWxMsgCode("");
            if (StringUtils.isEmpty(warnStrategy.getLowSmsMsgCode())) warnStrategy.setLowSmsMsgCode("");
            if (StringUtils.isEmpty(warnStrategy.getLowWxMsgCode())) warnStrategy.setLowWxMsgCode("");
            warnStrategyMapper.updateById(warnStrategy);

            //更新数据
            warnStrategyExtMapper.updateByStrategyid(request.getId());
            saveBatchExts(extData, warnStrategy, spId);

            //企业级操作日志
            LogVO vo = new LogVO();
            StringBuilder stringBuilder = new StringBuilder();
            String detail = LogUtil.compareEntity(warnStrategy, warn, WarnStrategy.class);
            log.info("LogVO-detail:{}", detail);
            if (detail.contains("行业：由【")) {
                String replace = detail.replace("【", "")
                        .replace("】", "").replace("行业:由", "")
                        .replace("变更为", "").trim();
                String[] split = replace.split(";");
                log.info("LogVO-split:{}", com.alibaba.fastjson.JSONObject.toJSONString(split));
                if (warnStrategy.getStrategyObj() == 1) {
                    List<Map<String, String>> industryType = equipmentService
                            .dictMap("Industry_type", null, spId);
                    log.info("LogVO-industryType:{}", industryType);
                    if (CollectionUtil.isNotEmpty(industryType) && split.length > 0) {
                        for (String s : split) {
                            for (Map<String, String> map : industryType) {
                                if (map.get("value").equals(s)) {
                                    detail = detail.replace(s, map.get("alias"));
                                    log.info("detail:{}", detail);
                                }
                            }
                        }
                    }
                } else {
                    if (split.length > 0) {
                        String[] splitNew = warnStrategy.getStrategyObjValues().split(";");
                        String[] splitOld = warn.getStrategyObjValues().split(";");
                        LambdaQueryWrapper<ServicePkgRecord> recordLambdaQueryWrapper = new LambdaQueryWrapper<>();
                        recordLambdaQueryWrapper.in(ServicePkgRecord::getId, split)
                                .eq(ServicePkgRecord::getSpId, spId)
                                .eq(ServicePkgRecord::getIsDeleted, 0);
                        List<ServicePkgRecord> pkgRecords = servicePkgRecordService.list(recordLambdaQueryWrapper);
                        log.info("LogVO-pkgRecords:{}", pkgRecords);
                        if (CollectionUtil.isNotEmpty(pkgRecords)) {
                            Map<Integer, String> servicePkgMap = pkgRecords.stream().collect(Collectors.toMap(ServicePkgRecord::getId, ServicePkgRecord::getPgkName, (a1, a2) -> a1));
                            StringBuilder sbOld = new StringBuilder();
                            for (String s : splitOld) {
                                if (!StringUtils.isEmpty(s) && servicePkgMap.containsKey(Integer.valueOf(s))) {
                                    sbOld.append(servicePkgMap.get(Integer.valueOf(s))).append(";");
                                }
                            }
                            if (sbOld.length() > 0) {
                                detail = detail.replace("行业：由【" + warn.getStrategyObjValues(), "行业：由【" +sbOld.toString());
                            }
                            StringBuilder sbNew = new StringBuilder();
                            for (String s : splitNew) {
                                if (!StringUtils.isEmpty(s) && servicePkgMap.containsKey(Integer.valueOf(s))) {
                                    sbNew.append(servicePkgMap.get(Integer.valueOf(s))).append(";");
                                }
                            }
                            if (sbNew.length() > 0) {
                                detail = detail.replace(warnStrategy.getStrategyObjValues(), sbNew.toString());
                            }
                        }
                    }
                }

            }
            Map<Integer, List<WarnStrategyExtRequest>> collect = extData.stream().
                    collect(Collectors.groupingBy(WarnStrategyExtRequest::getPushType, Collectors.toList()));
            detail = getLogRecord(detail, collect.get(2),"机器人外呼:");
            detail = getLogRecord(detail, collect.get(1),"短信消息:");
            stringBuilder.append(detail);
            vo.setDetail(stringBuilder.toString());
            log.info("LogVO-vo:{}", com.alibaba.fastjson.JSONObject.toJSONString(vo));
            LogRecordAspect.threadLocal.set(vo);
        } else if (source == 0 && checkSwitch == 0) {
            //新增审核记录
            insertCheck(request, spId);
            resMap.put("checkOpen", 0);
        }
        return resMap;
    }

    private String getLogRecord(String detail, List<WarnStrategyExtRequest> warns,String targetChar) {
        try {
            if (detail.contains(targetChar)) {
                List<Integer> integers = stringIndex(detail, targetChar);
                if (!CollectionUtils.isEmpty(integers)) {
                    Map<Integer, List<WarnStrategyExtRequest>> c = warns.stream()
                            .collect(Collectors.groupingBy(WarnStrategyExtRequest::getType, Collectors.toList()));
                    warns.sort((o1, o2) -> {
                        return o1.getReportNumberStart() - o1.getReportNumberStart();
                    });
                    List<WarnStrategyExtRequest> dExt = CollectionUtil.isNotEmpty(c.get(1))?c.get(1):new ArrayList<>();
                    List<WarnStrategyExtRequest> gExt = CollectionUtil.isNotEmpty(c.get(2))?c.get(2):new ArrayList<>();
                    log.info("dExt:{}", JSON.toJSONString(dExt));
                    log.info("gExt:{}",JSON.toJSONString(gExt));
                    String str = "";
                    for (WarnStrategyExtRequest w : dExt) {
                        str = str + "报警次数" + w.getReportNumberStart() + "-" + w.getReportNumberEnd() + "，推送给客户联系人级别" + w.getPushLevel() + "，企业员工（" + w.getPushStaffs() + "），额外推送手机号码：" + w.getCallPhones() + "";
                    }
                    str = dExt.size()<=0?"":targetChar+"报警值1" + "【" + str + "】";

                    String str1 = "";
                    for (WarnStrategyExtRequest w : gExt) {
                        str1 = str1 + "报警次数" + w.getReportNumberStart() + "-" + w.getReportNumberEnd() + "，推送给客户联系人级别" + w.getPushLevel() + "，企业员工（" + w.getPushStaffs() + "），额外推送手机号码：" + w.getCallPhones() + "";
                    }
                    str1 = gExt.size()<=0?"":targetChar+"报警值2" + "【" + str1 + "】";

                    String[] split = detail.split(targetChar);
                    if (split.length >= 3) {
                        detail = split[0] + str + split[1] + str1 + split[2];
                    } else {
                        detail = split[0] + str + split[1] + str1;
                    }
                }

            }
        } catch (Exception e) {
            log.error("getLogRecord-error:{}",e);
        }
        return detail;
    }

    public static List<Integer> stringIndex(String str, String targetChar) {
        List<Integer> positions = new ArrayList<>();
        int index = str.indexOf(targetChar);
        if (index != -1) {
            positions.add(index);
        }
        while (index != -1) {
            index = str.indexOf(targetChar, index + 1);
            if (index != -1) {
                positions.add(index);
            }
        }
        return positions;
    }

    private void checkHighLowType(SaveWarnStrategyRequest request) {
        Integer lowType = request.getLowType();
        Integer highType = request.getHighType();
        String highCallInterval = request.getHighCallInterval();
        String lowCallInterval = request.getLowCallInterval();
        String lowWxInterval = request.getLowWxInterval();
        String highWxInterval = request.getHighWxInterval();
        String highSendInterval = request.getHighSendInterval();
        String lowSendInterval = request.getLowSendInterval();
        String highReportInterval = request.getHighReportInterval();
        String lowReportInterval = request.getLowReportInterval();
        if (lowType != null)
            checkCodeAndType(lowType, lowCallInterval, lowSendInterval, lowReportInterval, lowWxInterval);
        if (highType != null)
            checkCodeAndType(highType, highCallInterval, highSendInterval, highReportInterval, highWxInterval);
    }

    private void checkCodeAndType(int type,
                                  String callInterval, String sendInterval
            , String reportInterval, String wxInterval) {
        if (StringUtils.isEmpty(callInterval)) {
            if (PushTypeEnum.getPushTypes(null, 4).contains(type))
                throw new BizException("请完善推送配置");
        } else if (StringUtils.isEmpty(sendInterval)) {
            if (PushTypeEnum.getPushTypes(null, 2).contains(type))
                throw new BizException("请完善推送配置");
        } else if (StringUtils.isEmpty(reportInterval)) {
            if (PushTypeEnum.getPushTypes(null, 1).contains(type))
                throw new BizException("请完善推送配置");
        } else if (StringUtils.isEmpty(wxInterval)) {
            if (PushTypeEnum.getPushTypes(null, 3).contains(type))
                throw new BizException("请完善推送配置");
        }
    }


    @Override
    public List<WarnStrategy> queryStrategy(SaveWarnStrategyRequest request, String spId, Long id) {
        String strategyObjValues = request.getStrategyObjValues();
        if (request.getStrategyObj() != 0 && StringUtils.isEmpty(strategyObjValues))
            throw new BizException("客户id或者行业id不能为空");
        String[] array = new String[1];

        if (!StringUtils.isEmpty(strategyObjValues) && strategyObjValues.contains(split)) {
            array = strategyObjValues.split(WarnStrategyServiceImpl.split);

        } else if (!StringUtils.isEmpty(strategyObjValues)) {
            array[0] = strategyObjValues;
        } else if (StringUtils.isEmpty(strategyObjValues)) {
            array = null;
        }
        List<WarnStrategy> warnStrategies = warnStrategyMapper
                .selectByIdStrategyObjValues(spId, array, request.getStrategyObj(), id);
        if (!CollectionUtil.isEmpty(warnStrategies) && array != null) {
            Set<WarnStrategy> res = new HashSet<>();
            String[] finalArray = array;
            warnStrategies.forEach(warnStrategy -> {
                if (!StringUtils.isEmpty(warnStrategy.getStrategyObjValues())) {
                    String[] split = warnStrategy.getStrategyObjValues()
                            .split(WarnStrategyServiceImpl.split);
                    List<String> list = new ArrayList<>(Arrays.asList(split));
                    for (String s : finalArray) {
                        if (list.contains(s)) {
                            res.add(warnStrategy);
                            break;
                        }
                    }
                }
            });
            if (CollectionUtil.isEmpty(res)) {
                return new ArrayList<>();
            }
        }


        return warnStrategies;

    }

    /**
     * 获取详情
     *
     * @param id
     * @return
     */
    @Override
    public WarnStrategyResponse warnStrategyInfo(Long id) {
        WarnStrategyResponse warnStrategyResponse = new WarnStrategyResponse();
        List<WarnStrategyExtResponse> extData = new ArrayList<>();
        WarnStrategy warnStrategy = warnStrategyMapper.selectById(id);
        if (warnStrategy == null) throw new BizException("数据不存在");
        BeanUtils.copyProperties(warnStrategy, warnStrategyResponse);
        QueryWrapper<WarnStrategyExt> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(WarnStrategyExt::getIsDeleted, 0)
                .eq(WarnStrategyExt::getStrategyId, id);
        List<WarnStrategyExt> exts = warnStrategyExtMapper.selectList(queryWrapper);
        if (!CollectionUtil.isEmpty(exts)) {
            for (WarnStrategyExt ext : exts) {
                WarnStrategyExtResponse warnStrategyExt = new WarnStrategyExtResponse();
                BeanUtils.copyProperties(ext, warnStrategyExt);
                String pushStaffs = ext.getPushStaffs();
                List<String> pushStaffList = new ArrayList<>();
                if (!StringUtils.isEmpty(pushStaffs) && pushStaffs.contains(split)) {
                    String[] split = pushStaffs.split(WarnStrategyServiceImpl.split);
                    pushStaffList = new ArrayList<>(Arrays.asList(split));
                }
                warnStrategyExt.setPushStaffs(pushStaffList);
                extData.add(warnStrategyExt);
            }
        }
        Map<Integer, List<WarnStrategyExtResponse>> collect = extData.stream()
                .collect(Collectors.groupingBy(WarnStrategyExtResponse::getPushType,
                        Collectors.toList()));
        warnStrategyResponse.setExtSMSData(collect.get(1));
        warnStrategyResponse.setExtCallData(collect.get(2));
        //查询微信消息模板内容
        //批量查询字典
        List<DictionaryItemRespDTO> orgMapSubsCodeList = holder.getDictionaryByKey(ORG_MAP_SUBSCODE);
        String orgCode;
        if (!CollectionUtils.isEmpty(orgMapSubsCodeList)) {
            orgCode = orgMapSubsCodeList.get(0).getValue();
        } else {
            orgCode = companyService.getOrgCode(warnStrategy.getSpId(), null);
        }
        if (StringUtils.isEmpty(warnStrategy.getHighWxMsgCode())) {
            String smsWXContent = getConTent(orgCode, warnStrategy.getSpId(), warnStrategy.getHighWxMsgCode());
            warnStrategyResponse.setHighWxMsgCodeContent(smsWXContent);
        }

        //查询短信消息模板内容
        if (StringUtils.isEmpty(warnStrategy.getHighSmsMsgCode())) {
            String smsSmsContent = getConTent(orgCode, warnStrategy.getSpId(), warnStrategy.getHighSmsMsgCode());
            warnStrategyResponse.setHighSmsMsgCodeContent(smsSmsContent);
        }

        //查询微信消息模板内容
        if (StringUtils.isEmpty(warnStrategy.getLowWxMsgCode())) {
            String smsWXContent = getConTent(orgCode, warnStrategy.getSpId(), warnStrategy.getLowWxMsgCode());
            warnStrategyResponse.setLowWxMsgCodeContent(smsWXContent);
        }

        //查询短信消息模板内容
        if (StringUtils.isEmpty(warnStrategy.getLowSmsMsgCode())) {
            String smsSmsContent = getConTent(orgCode, warnStrategy.getSpId(), warnStrategy.getLowSmsMsgCode());
            warnStrategyResponse.setLowSmsMsgCodeContent(smsSmsContent);
        }

        //根据客户id获取客户名称、行业名称
        String strategyObjValues = warnStrategy.getStrategyObjValues();
        if (!StringUtils.isEmpty(strategyObjValues)
                && strategyObjValues.contains(split)) {
            String[] r = strategyObjValues.split(WarnStrategyServiceImpl.split);
            warnStrategyResponse.setObjLists(r);
        }
        warnStrategyResponse.setCreatedAt(DateUtil.format(warnStrategy
                .getCreatedAt(), "yy-MM-dd HH:mm:ss"));
        warnStrategyResponse.setUpdatedAt(DateUtil.format(warnStrategy
                .getUpdatedAt(), "yyyy-MM-dd HH:mm:ss"));
        Field[] fields = warnStrategyResponse.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Object o = field.get(warnStrategyResponse);
                if ("0".equals(o) && (!field.getName().equals("strategyObj")
                        || !field.getName().equals("strategyEquipment")
                        || !field.getName().equals("remark")
                        || !field.getName().equals("ruleName")
                        || !field.getName().equals("highType")
                        || !field.getName().equals("lowType"))) {
                    field.set(warnStrategyResponse, null);
                }
            } catch (IllegalAccessException e) {
                log.error("warnStrategyInfo-error:{}", e);
            }
        }

        return warnStrategyResponse;
    }

    //根据code查询消息内容
    public String getConTent(String orgCode, String spId, String msgCode) {
        TaskDetailParamDTO smsTaskDetailParam = new TaskDetailParamDTO();
        smsTaskDetailParam.setSpId(spId);
        smsTaskDetailParam.setOrgCode(orgCode);
        smsTaskDetailParam.setCode(msgCode);
        TaskDetailRespDTO smsTaskDetailResp = sendMessageService.getMsgTemplateContent(smsTaskDetailParam);
        String smsSmsContent = smsTaskDetailResp.getTemplateContent();
        return smsSmsContent;
    }

    /**
     * 根据spid获取数据
     *
     * @return
     */
    @Override
    public PageUtil<WarnStrategyRes> warnStrategyList(StrategyListRequest request) {
        String spId = ApplicationUtils.getWorkingSpId();
        int templateType = fieldTemplateService.getBySpId(spId);
        request.setTemplateType(templateType);
        log.info("warnStrategyList-templateType:{}", com.alibaba.fastjson.
                JSONObject.toJSONString(request));
        Page<WarnStrategy> page = PageHelper.startPage(request.getPage(), request.getPageSize());
        WarnStrategy warnStrategy = new WarnStrategy();
        BeanUtils.copyProperties(request, warnStrategy);
        warnStrategy.setSpId(spId);
        if (request.getLowReport() != null) warnStrategy.setLowReport(request.getLowReport() + "");
        if (request.getHighReport() != null) warnStrategy.setHighReport(request.getHighReport() + "");
        if (request.getCreatedAt() != null) {
            DateTime parse = DateUtil.parse(request.getCreatedAt(), "yyyy-MM-dd");
            warnStrategy.setCreatedAt(parse);
            warnStrategy.setCreatedAtEnd(DateUtil.offsetDay(parse, 1));
        }
        List<String> splits = new ArrayList<>();
        if (request.getStrategyObj() != null) {
            warnStrategy.setStrategyObj(Integer.parseInt(request.getStrategyObj()));
            String objValues = request.getStrategyObjValues();
            if (!StringUtils.isEmpty(objValues)
                    && objValues.contains(split)) {
                splits = new ArrayList<>(Arrays.asList(objValues.split(WarnStrategyServiceImpl.split)));

            } else if (!StringUtils.isEmpty(objValues)) {
                splits.add(objValues);
            }
        }

        List<WarnStrategy> warnStrategies = warnStrategyMapper.selectListByCondition(warnStrategy, splits);
        List<WarnStrategyRes> warnStrategyResList = new ArrayList<>();
        for (WarnStrategy strategy : warnStrategies) {
            String objValues = strategy.getStrategyObjValues();
            if (!"0".equals(request.getStrategyObj()) && !StringUtils.isEmpty(request.getStrategyObjValues())
                    && request.getStrategyObjValues().contains(split)) {
                //行业和客户选择的情况下
                int i = 0;
                String[] split = objValues.split(WarnStrategyServiceImpl.split);
                for (String objValue : splits) {
                    if (new ArrayList<>(Arrays.asList(split)).contains(objValue)) {
                        i = 1;
                        continue;
                    }
                }
                if (i == 0) {
                    continue;
                }
            }
            WarnStrategyRes warnStrategyRes = new WarnStrategyRes();
            BeanUtils.copyProperties(strategy, warnStrategyRes);
            if (strategy.getCreatedAt() != null)
                warnStrategyRes.setCreatedAt(DateUtil.format(strategy.getCreatedAt(), format));
            if (strategy.getUpdatedAt() != null)
                warnStrategyRes.setUpdatedAt(DateUtil.format(strategy.getUpdatedAt(), format));
            warnStrategyResList.add(warnStrategyRes);
        }

        //进行转换
//        warnStrategyResList.forEach(warn -> {
//            getComsumerIndustryName(spId, warn, request.getTemplateType());
//        });
        getComsumerIndustryNames(spId, warnStrategyResList, request.getTemplateType());
        //区分模板
        List<PageColumns> add = new ArrayList<>();
        if (TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == request.getTemplateType()) {
            add = PageColumnConst.add(PageColumnConst.StrategyVccTitles, PageColumnConst.StrategyVccIndices);
        } else {
            add = PageColumnConst.add(PageColumnConst.StrategyTitles, PageColumnConst.StrategyIndices);
        }
        PageUtil pageInfo = new PageUtil<>(request.getPage(),
                request.getPageSize(), page.getTotal(), warnStrategyResList, add);

        return pageInfo;
    }

    public void getComsumerIndustryNames(String spId, List<WarnStrategyRes> warnList, Integer templateType) {
        log.info("getComsumerIndustryName-params:{},{},{},", spId,
                com.alibaba.fastjson.JSONObject.toJSONString(warnList),
                templateType);
        //客户id
        List<Integer> consumerIds = new ArrayList<>();
        //服务套餐id
        List<Integer> pkgIds = new ArrayList<>();
        for (WarnStrategyRes warnStrategyRes : warnList) {
            String[] r = warnStrategyRes.getStrategyObjValues().split(WarnStrategyServiceImpl.split);
            if (warnStrategyRes.getStrategyObj() == 2) {
                for (String consumerId : r) {
                    consumerIds.add(Integer.valueOf(consumerId));
                }
            } else if (warnStrategyRes.getStrategyObj() == 3) {
                for (String pkgId : r) {
                    pkgIds.add(Integer.valueOf(pkgId));
                }
            }
        }
        Map<Integer, Consumer> consumerMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(consumerIds)) {
            LambdaQueryWrapper<Consumer> consumerLambdaQueryWrapper = new LambdaQueryWrapper<>();
            consumerLambdaQueryWrapper.in(Consumer::getId, consumerIds)
                    .eq(Consumer::getSpId, spId)
                    .eq(Consumer::getIsDeleted, 0);
            List<Consumer> consumerList = consumerMapper.selectList(consumerLambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(consumerList)) {
                consumerMap = consumerList.stream().collect(Collectors.toMap(Consumer::getId, Consumer -> Consumer, (a1, a2) -> a1));
            }
        }
        Map<Integer, ServicePkgRecord> pkgRecordMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(pkgIds)) {
            LambdaQueryWrapper<ServicePkgRecord> recordLambdaQueryWrapper = new LambdaQueryWrapper<>();
            recordLambdaQueryWrapper.in(ServicePkgRecord::getId, pkgIds)
                    .eq(ServicePkgRecord::getSpId, spId)
                    .eq(ServicePkgRecord::getIsDeleted, 0);
            List<ServicePkgRecord> pkgRecords = servicePkgRecordService.list(recordLambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(pkgRecords)) {
                pkgRecordMap = pkgRecords.stream().collect(Collectors.toMap(ServicePkgRecord::getId, ServicePkgRecord -> ServicePkgRecord, (a1, a2) -> a1));
            }
        }
        //按照行业选择
        List<Map<String, String>> industryType = equipmentService
                .dictMap("Industry_type", null, spId);
        for (WarnStrategyRes warn : warnList) {
            //根据客户id获取客户名称、行业名称
            String values = "";
            String strategyObjValues = warn.getStrategyObjValues();
            if (!StringUtils.isEmpty(strategyObjValues)
                    && strategyObjValues.contains(split)) {

                String[] r = strategyObjValues.split(WarnStrategyServiceImpl.split);
                if (r.length > 0) {
                    if (warn.getStrategyObj() == 1) {
                        //按照行业选择
                        if (!CollectionUtil.isEmpty(industryType)) {
                            for (String s : r) {
                                for (Map<String, String> map : industryType) {
                                    if (map.get("value").equals(s)) {
                                        values = map.get("alias") + "、" + values;
                                    }
                                }
                            }

                        }
                    } else if (warn.getStrategyObj() == 2){
                        if (templateType != null && TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == templateType) {
                            //按照客户选择
                            //values = consumerMapper.selectVccNames(spId, r);
                            for (String key : r) {
                                if (consumerMap.containsKey(Integer.valueOf(key))) {
                                    Consumer consumer = consumerMap.get(Integer.valueOf(key));
                                    values = values + consumer.getPhone() + "（" + consumer.getMemberId() + "）、";
                                }
                            }
                        } else {
                            //按照客户选择
                            //values = consumerMapper.selectNames(spId, r);
                            for (String key : r) {
                                if (consumerMap.containsKey(Integer.valueOf(key))) {
                                    Consumer consumer = consumerMap.get(Integer.valueOf(key));
                                    values = values + consumer.getCustName() + "（" + consumer.getSubsCode() + "）" + consumer.getName() +"、";
                                }
                            }
                        }
                    }else {
                        for (String key : r) {
                            if (pkgRecordMap.containsKey(Integer.valueOf(key))) {
                                values = values + pkgRecordMap.get(Integer.valueOf(key)).getPgkName() + "、";
                            }
                        }

                    }
                    if (values.length() > 0) values = values.substring(0, values.length() - 1);
                }
            }
            warn.setStrategyObjValues(values);
            if (warn.getStrategyObj()==0) warn.setStrategyObjValues("所有客户");
        }
    }

    public void getComsumerIndustryName(String spId, WarnStrategyRes warn, Integer templateType) {
        log.info("getComsumerIndustryName-params:{},{},{},", spId,
                com.alibaba.fastjson.JSONObject.toJSONString(warn),
                templateType);
        //根据客户id获取客户名称、行业名称
        String values = "";
        String strategyObjValues = warn.getStrategyObjValues();
        if (!StringUtils.isEmpty(strategyObjValues)
                && strategyObjValues.contains(split)) {

            String[] r = strategyObjValues.split(WarnStrategyServiceImpl.split);
            if (r.length > 0) {
                if (warn.getStrategyObj() == 1) {
                    //按照行业选择
                    List<Map<String, String>> industryType = equipmentService
                            .dictMap("Industry_type", null, spId);
                    if (!CollectionUtil.isEmpty(industryType)) {
                        for (String s : r) {
                            for (Map<String, String> map : industryType) {
                                if (map.get("value").equals(s)) {
                                    values = map.get("alias") + "、" + values;
                                }
                            }
                        }

                    }
                    if (values.length() > 0) values = values.substring(0, values.length() - 1);
                } else if (warn.getStrategyObj() == 2){
                    if (templateType != null && TemplateTypeEnum.TEMPLATE_TYPE_2.getCode() == templateType) {
                        //按照客户选择
                        values = consumerMapper.selectVccNames(spId, r);
                    } else {
                        //按照客户选择
                        values = consumerMapper.selectNames(spId, r);
                    }

                }else {
                    LambdaQueryWrapper<ServicePkgRecord> recordLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    recordLambdaQueryWrapper.in(ServicePkgRecord::getId, r)
                            .eq(ServicePkgRecord::getSpId, spId)
                            .eq(ServicePkgRecord::getIsDeleted, 0);
                    List<ServicePkgRecord> pkgRecords = servicePkgRecordService.list(recordLambdaQueryWrapper);
                    if (!CollectionUtils.isEmpty(pkgRecords)) {
                        for (ServicePkgRecord pkgRecord : pkgRecords) {
                            values = values + pkgRecord.getPgkName() + "、";
                        }
                    }
                    if (values.length() > 0) values = values.substring(0, values.length() - 1);
                }
            }
        }
        warn.setStrategyObjValues(values);
    }

    /**
     * 批量删除
     * type:0删除 1启用
     *
     * @param request
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteWarnStrategy(DeleteWarnStrategyRequest request) {
        int type = 0;
        int delete = 1;
        List<String> ids = request.getWarnStrategyIds();
        LambdaQueryWrapper<WarnStrategy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(WarnStrategy::getIsDeleted, 0).in(WarnStrategy::getId, ids);
        List<WarnStrategy> warnStrategies = warnStrategyMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(warnStrategies)) {
            //企业级操作日志
            LogVO vo = new LogVO();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < warnStrategies.size(); i++) {
                sb.append(warnStrategies.get(i).getRuleName());
                if (i != warnStrategies.size() - 1) {
                    sb.append("、");
                }
            }
            vo.setDetail("【" + "规则名称：" + sb + "】" + "成功");
            vo.setCommonInfo(sb.toString());
            LogRecordAspect.threadLocal.set(vo);
        }
        if (!CollectionUtil.isEmpty(ids))
            warnStrategyMapper.updateByIds(ids, type, delete);
        UpdateWrapper<WarnStrategyCheck> wrapper = new UpdateWrapper<>();
        wrapper.lambda().or().eq(WarnStrategyCheck::getIsDeleted, 0)
                .eq(WarnStrategyCheck::getCheckStatus, 0)
                .in(WarnStrategyCheck::getRuleId, ids);
        WarnStrategyCheck check = new WarnStrategyCheck();
        check.setRemark("策略删除");
        check.setCheckPersonName(ApplicationUtils.getWorkingUser().getName());
        check.setCheckPersonCode(ApplicationUtils.getWorkingUser().getUsername());
        check.setCheckTime(DateUtil.format(new Date(), format));
        warnStrategyCheckMapper.update(check, wrapper);

    }

    /**
     * 禁用启用
     *
     * @param request
     */
    @Override
    public void updateStatus(UpdateStrategyRequest request) {
        int type = 1;
        List<String> ids = request.getWarnStrategyIds();
        if (!CollectionUtil.isEmpty(ids)) {
            LambdaQueryWrapper<WarnStrategy> wrapper = new LambdaQueryWrapper<>();
            wrapper.or().eq(WarnStrategy::getIsDeleted, 0).in(WarnStrategy::getId, ids);
            List<WarnStrategy> warnStrategies = warnStrategyMapper.selectList(wrapper);
            if (CollectionUtil.isNotEmpty(warnStrategies)) {
                //企业级操作日志
                LogVO vo = new LogVO();
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < warnStrategies.size(); i++) {
                    sb.append(warnStrategies.get(i).getRuleName());
                    if (i != warnStrategies.size() - 1) {
                        sb.append("、");
                    }
                }
                vo.setDetail("【" + "规则名称：" + sb + "】" + "成功");
                if (warnStrategies.size() > 1) {
                    if (request.getType() == 0) {
                        vo.setOperateRecordEnum(OperateRecordEnum.OPERATE_TYPE_42);
                    } else {
                        vo.setOperateRecordEnum(OperateRecordEnum.OPERATE_TYPE_43);
                    }
                } else {
                    if (request.getType() == 0) {
                        vo.setOperateRecordEnum(OperateRecordEnum.OPERATE_TYPE_25);
                    } else {
                        vo.setOperateRecordEnum(OperateRecordEnum.OPERATE_TYPE_41);
                    }
                }
                vo.setCommonInfo(sb.toString());
                LogRecordAspect.threadLocal.set(vo);
            }
            warnStrategyMapper.updateByIds(ids, type, request.getType());

        }
    }

    /**
     * 报警手动暂停
     *
     * @param imei
     * @param taskIdentificationCode
     */
    @Override
    public void killWarning(String imei, String taskIdentificationCode) {
        List<String> keys = getKeys(redisTemplate, Constants.WARNING_EQUIPMENT + ":*");
        log.info("killWarning-keys:{}",JSON.toJSONString(keys));
        if (!imei.contains("-"))imei=imei+"-1-0";
        Map<String, Object> cacheMap = redisCache.getCacheMap(Constants.WARNING_EQUIPMENT + ":" + imei);
        log.info("killWarning-cacheMap:{},{}",JSON.toJSONString(cacheMap),imei);
        //直接手动暂停任务
        if (cacheMap != null && cacheMap.size() > 0) {
            redisCache.deleteObject(Constants.WARNING_EQUIPMENT + ":" + imei);
        }

        LambdaQueryWrapper<WarningRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(WarningRecord::getIsDeleted, 0).eq(WarningRecord::getTaskIdentificationCode, taskIdentificationCode);
        List<WarningRecord> warningRecords = warningRecordMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(warningRecords)) {
            WarningRecord warningRecord = warningRecords.get(0);
            WarnStrategy warnStrategy = warnStrategyMapper.selectById(warningRecord.getTriggerRuleId());
            String ruleName = "";
            if (warnStrategy != null) ruleName = warnStrategy.getRuleName();
            //企业级操作日志
            LogVO vo = new LogVO();
            StringBuilder sb = new StringBuilder();
            sb.append(ruleName + "&" + DateUtil.format(warningRecord.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
            vo.setDetail("【" + "规则名称：" + ruleName + "】" + "成功");
            vo.setCommonInfo(sb.toString());
            LogRecordAspect.threadLocal.set(vo);
        }
        //更新数据
        updateRecordStatus(imei, taskIdentificationCode, 1);
        //清除策略计数
        String deviceId = imei.replace("-1-0", "");
        Dtu dtu = equipmentService.getBaseMapper().selectById(deviceId);
        if (null != dtu) {
            String strategyKey = Constants.ALARM_STRATEGY + deviceId + dtu.getSpId();
            log.info("strategyKey:{}",strategyKey);
            redisCache.deleteObject(strategyKey);
        }
    }

    @Override
    public void killInformRecord(String imei, String taskIdentificationCode) {
        List<String> keys = getKeys(redisTemplate, Constants.WARNING_EQUIPMENT_RUNNING + ":*");
        log.info("killWarning-keys:{}",JSON.toJSONString(keys));
        if (!imei.contains("-"))imei=imei+"-1-0";
        Map<String, Object> cacheMap = redisCache.getCacheMap(Constants.WARNING_EQUIPMENT_RUNNING + ":" + imei);
        log.info("killWarning-cacheMap:{},{}",JSON.toJSONString(cacheMap),imei);
        //直接手动暂停任务
        if (cacheMap != null && cacheMap.size() > 0) {
            redisCache.deleteObject(Constants.WARNING_EQUIPMENT_RUNNING + ":" + imei);
            redisCache.deleteObject(Constants.WARNING_EQUIPMENT_RUNNING_BREAKDOWN + ":" + imei);
        }

        LambdaQueryWrapper<InformRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(InformRecord::getIsDeleted, 0).eq(InformRecord::getTaskIdentificationCode, taskIdentificationCode);
        List<InformRecord> informRecords = informRecordMapper.selectList(queryWrapper);
        if (CollectionUtil.isNotEmpty(informRecords)) {
            InformRecord warningRecord = informRecords.get(0);
            WarnStrategy warnStrategy = warnStrategyMapper.selectById(warningRecord.getTriggerRuleId());
            String ruleName = "";
            if (warnStrategy != null) ruleName = warnStrategy.getRuleName();
            //企业级操作日志
            LogVO vo = new LogVO();
            StringBuilder sb = new StringBuilder();
            sb.append(ruleName + "&" + DateUtil.format(warningRecord.getStartTime(), "yyyy-MM-dd HH:mm:ss"));
            vo.setDetail("【" + "规则名称：" + ruleName + "】" + "成功");
            vo.setCommonInfo(sb.toString());
            LogRecordAspect.threadLocal.set(vo);
        }
        //更新数据
        updateInformRecordStatus(imei, taskIdentificationCode, 1);
    }

    public static List<String> getKeys(RedisTemplate redisTemplate, String patternKey) {
        long start = System.currentTimeMillis();
        List<String> result = new ArrayList<>();
        try {
            ScanOptions options = ScanOptions.scanOptions()
                    .count(1000)
                    .match(patternKey).build();
            RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
            Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection ->
                    new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
            while (cursor.hasNext()) {
                result.add(cursor.next().toString());
            }
            cursor.close();
        } catch (IOException e) {
            log.error("getKeys-error:{}", e);
            return result;
        }
        log.info("scan扫描共耗时：{} ms key数量：{}", System.currentTimeMillis() - start, result.size());
        return result;
    }

    //因行业变化停止的策略
    @Override
    public void killWarningByIndustry(String consumerId) {
        log.info("killWarningByIndustry---行业变化，需要停止当前策略:影响的客户id:{}", consumerId);
        //根据客户id获取其设备
        List<Dtu> dtus = equipmentService.getEqumentsByConsumerId(consumerId);
        if (!CollectionUtil.isEmpty(dtus)) {
            dtus.forEach(dtu -> {
                Object code = "";
                String imei = dtu.getIMEI();
                List<String> keys = getKeys(redisTemplate, Constants.WARNING_EQUIPMENT + ":" + imei + "*");
                //直接手动暂停任务
                if (keys != null && keys.size() > 0) {
                    for (String key : keys) {
                        Map<String, Object> cacheMap = redisCache.getCacheMap(key);
                        if (cacheMap != null && cacheMap.size() > 0) {
                            code = cacheMap.get("identificationCode");
                            redisCache.deleteObject(key);
                        }
                    }
                }
                //更新数据
                if (code != null) updateRecordStatus(imei, code + "", 1);
            });

        }

    }

    /**
     * 本地消息
     *
     * @return
     */
    @Override
    public Map<String, List<LocalMessageResponse>> localMessage() {
        String spId = ApplicationUtils.getWorkingSpId();
        Map<String, List<LocalMessageResponse>> resultMap = new HashMap<>();
        List<LocalMessageResponse> res = new ArrayList<>();
        Date date = new Date();
        DateTime dateTime = DateUtil.offsetDay(date, -7);
        List<WarningRecord> responses = warningRecordMapper.selectContents(dateTime, spId);
        for (WarningRecord warningRecord : responses) {
            LocalMessageResponse localMessageResponse = new LocalMessageResponse();
            BeanUtils.copyProperties(warningRecord, localMessageResponse);
            localMessageResponse.
                    setCreatedAt(DateUtil.format(warningRecord.getCreatedAt(), format));
            res.add(localMessageResponse);
        }
        resultMap.put("list", res);


        return resultMap;

    }

    @Override
    public PageUtil<StaffListResponse> staffList(StaffListRequest request) {
        log.info("staffList-入参:{}", com.alibaba.fastjson.JSONObject.toJSONString(request));
        List<StaffListResponse> data = new ArrayList<>();
        int total = 0;
        String sType = null;
        if ("1".equals(request.getType())) {
            sType = "S";
        } else if ("2".equals(request.getType())) {
            sType = "W";
        } else if ("0".equals(request.getType())) {
            sType = "A";
        }
        try {
            UserBackend workingUser = ApplicationUtils.getWorkingUser();
            String token = workingUser.getToken();
            log.info("staffList-token:{}", token);
            JSONObject orgAll = provider.getStaffList(token,
                    request.getOrgCode(), request.getPage(), request.getPageSize(),
                    request.getPhone(), request.getPosition(), request.getStaffCode(), request.getStaffName(),
                    "A", sType);
            if (orgAll != null && !CollectionUtil.isEmpty(orgAll.getJSONArray("datas"))) {
                JSONArray datas = orgAll.getJSONArray("datas");
                datas.forEach(o -> {
                    StaffListResponse staffListResponse = new StaffListResponse();
                    com.alibaba.fastjson.JSONObject object = com.alibaba.fastjson.JSONObject.parseObject(o + "");
                    staffListResponse.setOrgName(object.getString("orgNames"));
                    staffListResponse.setPhone(object.getString("phone"));
                    staffListResponse.setPosition(object.getString("extStr03"));
                    staffListResponse.setStaffCode(object.getString("staffCode"));
                    staffListResponse.setStaffName(object.getString("staffName"));
                    staffListResponse.setStatus("0");
                    //                员工类型（S:公司员工,W 外来员工,A:全部员工）
                    String staffType = object.getString("staffType") == null ?
                            "A" : object.getString("staffType");
                    int type = 0;
                    if (staffType.equals("S")) {
                        type = 1;
                    } else if (staffType.equals("W")) {
                        type = 2;
                    }
                    staffListResponse.setType(type);
                    data.add(staffListResponse);
                });

                total = orgAll.getInt("totalSize");
            }
        } catch (Exception e) {
            log.error("staffList-error:{}", e);
        }

        PageUtil pageInfo = new PageUtil<>(request.getPage(),
                request.getPageSize(), total, data);

        return pageInfo;
    }

    @Override
    public Object departmentList() {
        Object object = new Object();
        try {
            UserBackend workingUser = ApplicationUtils.getWorkingUser();
            String token = workingUser.getToken();
            log.info("departmentList-token:{}", token);
            JSONObject orgAll = provider.getOrgAll(token);
            if (orgAll != null && orgAll.getJSONArray("items") != null) {
                object = orgAll.getJSONArray("items");
            }
        } catch (Exception e) {
            log.error("departmentList-error:{}", e);
        }
        return object;
    }

    @Override
    public Object checkStrategyInfo(Long id) {

        String spId = ApplicationUtils.getWorkingSpId();
        QueryWrapper<FieldTemplate> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or().eq(FieldTemplate::getIsDeleted, 0)
                .eq(FieldTemplate::getSpId, spId);
        Integer templateType = null;
        List<FieldTemplate> fieldTemplates = fieldTemplateMapper.selectList(queryWrapper);
        if (!CollectionUtil.isEmpty(fieldTemplates)) {
            templateType = fieldTemplates.get(0).getTemplateType();
        }
        WarnStrategyCheck check = warnStrategyCheckMapper.selectById(id);
        if (check == null || StringUtils.isEmpty(check.getRuleJsonData())) {
            return new JSONObject();
        }
        List<String> strings = new ArrayList<>();
        String ruleJsonData = check.getRuleJsonData();
        com.alibaba.fastjson.JSONObject object = com.alibaba.fastjson.JSONObject.parseObject(ruleJsonData);
        String values = object.getString("strategyObjValues");
        if (!StringUtils.isEmpty(values) && values.contains(split)) {
            strings = new ArrayList<>(Arrays.asList(values.split(split)));
        }
        object.put("objLists", strings);
        WarnStrategyRes warnStrategy = new WarnStrategyRes();
        warnStrategy.setStrategyObjValues(values);
        warnStrategy.setStrategyObj(Integer.parseInt(object.getString("strategyObj") + ""));
        getComsumerIndustryName("", warnStrategy, templateType);
        object.put("strategyObjValues", warnStrategy.getStrategyObjValues());

        com.alibaba.fastjson.JSONArray extDatas = new com.alibaba.fastjson.JSONArray();
        com.alibaba.fastjson.JSONArray extData = object.getJSONArray("extData");
        if (!CollectionUtil.isEmpty(extData)) {
            extData.forEach(o -> {
                com.alibaba.fastjson.JSONObject ext = com.alibaba.fastjson.JSONObject.parseObject(o + "");
                String pushStaffs = ext.getString("pushStaffs");
                if (StringUtils.isEmpty(pushStaffs)) {
                    ext.put("pushStaffs", new ArrayList<>(Arrays.asList(pushStaffs.split(split))));
                } else {
                    ext.put("pushStaffs", new ArrayList<>());
                }
                extDatas.add(ext);
            });
        }
        object.put("extData", extDatas);

        return object;
    }

    public void updateRecordStatus(String imei, String taskIdentificationCode, int status) {
        WarningRecord warningRecord = new WarningRecord();
        warningRecord.setTaskIdentificationCode(taskIdentificationCode);
        warningRecord.setStatus(status);
        warningRecord.setEndTime(new Date());
        QueryWrapper<WarningRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or()
                .eq(WarningRecord::getTaskIdentificationCode, taskIdentificationCode);
        warningRecordMapper.update(warningRecord, queryWrapper);
    }

    public void updateInformRecordStatus(String imei, String taskIdentificationCode, int status) {
        InformRecord warningRecord = new InformRecord();
        warningRecord.setTaskIdentificationCode(taskIdentificationCode);
        warningRecord.setEndTime(new Date());
        warningRecord.setStatus(status);
        QueryWrapper<InformRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or()
                .eq(InformRecord::getTaskIdentificationCode, taskIdentificationCode);
        informRecordMapper.update(warningRecord, queryWrapper);
    }


    private void saveBatchExts(List<WarnStrategyExtRequest> extData, WarnStrategy warnStrategy, String spId) {
        checkOverlap(extData);
        List<WarnStrategyExt> exts = new ArrayList<>();
        if (!CollectionUtil.isEmpty(extData)) {
            extData.forEach(warnStrategyExtRequest -> {
                WarnStrategyExt warnStrategyExt = new WarnStrategyExt();
                if ( !StringUtils.isEmpty(warnStrategyExtRequest.getCallPhones()) ){
                    String callPhones = warnStrategyExtRequest.getCallPhones().replace("；",split);
                    warnStrategyExtRequest.setCallPhones(callPhones);
                }
                BeanUtils.copyProperties(warnStrategyExtRequest, warnStrategyExt);
                warnStrategyExt.setStrategyId(warnStrategy.getId());
                warnStrategyExt.setSpId(spId);
                if (warnStrategyExtRequest.getPushType() == 1)
                    warnStrategyExt.setSendPhones(warnStrategyExtRequest.getCallPhones());
                if (!StringUtils.isEmpty(warnStrategyExtRequest.getPushStaffs()))
                    warnStrategyExt.setPushStaffs(warnStrategyExtRequest
                            .getPushStaffs()
                            .lastIndexOf(split) == warnStrategyExtRequest
                            .getPushStaffs().length() - 1 ? warnStrategyExtRequest
                            .getPushStaffs() : warnStrategyExtRequest
                            .getPushStaffs() + split);
                if (!StringUtils.isEmpty(warnStrategyExtRequest.getCallPhones()))
                    warnStrategyExt.setCallPhones(warnStrategyExtRequest
                            .getCallPhones()
                            .lastIndexOf(split) == warnStrategyExtRequest
                            .getCallPhones().length() - 1 ? warnStrategyExtRequest
                            .getCallPhones() : warnStrategyExtRequest
                            .getCallPhones() + split);

                if (!StringUtils.isEmpty(warnStrategyExtRequest.getSendPhones()))
                    warnStrategyExt.setSendPhones(warnStrategyExtRequest
                            .getSendPhones()
                            .lastIndexOf(split) == warnStrategyExtRequest
                            .getSendPhones().length() - 1 ? warnStrategyExtRequest
                            .getSendPhones() : warnStrategyExtRequest
                            .getSendPhones() + split);
                exts.add(warnStrategyExt);
            });
            warnStrategyExtMapper.insertBatch(exts);
        }
    }

    private void checkOverlap(List<WarnStrategyExtRequest> extData) {
        List<WarnStrategyExtRequest> extDataFilter = extData.stream().filter(s -> {
            return s.getType() == null || s.getReportNumberEnd() == null ||
                    s.getReportNumberStart() == null;
        }).collect(Collectors.toList());
        Map<Integer, List<WarnStrategyExtRequest>> collect = extDataFilter.stream()
                .collect(Collectors.groupingBy(WarnStrategyExtRequest::getType, Collectors.toList()));
        collect.forEach((integer, warnStrategyExtRequests) -> {
            Set<Integer> set = new HashSet<>();
            for (WarnStrategyExtRequest warn : warnStrategyExtRequests) {
                if (warn.getReportNumberStart() == null || warn.getPushLevel() == null)
                    throw new BizException("报警次数请按格式填写");
                for (Integer i = warn.getReportNumberStart(); i < warn.getReportNumberEnd(); i++) {
                    if (set.contains(i)) throw new BizException("报警次数不能重叠");
                    set.add(i);
                }
            }

        });
    }

    public List<BusinessNotice> getBusinessNotices(String spId) {
        QueryWrapper<BusinessNotice> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or().eq(BusinessNotice::getIsDeleted, 0)
                .eq(BusinessNotice::getSpId, spId)
                .eq(BusinessNotice::getParamCode, BusinessNoticeParam.ALERT_STRATEGY_CHECK.getCode());
        return businessNoticeMapper.selectList(queryWrapper);
    }

    private void insertCheck(SaveWarnStrategyRequest request, String spId) {
        Long id = request.getId();
        if (id != null) {
            QueryWrapper<WarnStrategyCheck> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().or().eq(WarnStrategyCheck::getIsDeleted, 0)
                    .eq(WarnStrategyCheck::getRuleId, id)
                    .in(WarnStrategyCheck::getCheckStatus, 0);
            List<WarnStrategyCheck> warnStrategyChecks = warnStrategyCheckMapper.selectList(queryWrapper);
            if (!CollectionUtil.isEmpty(warnStrategyChecks)) throw new BizException("当前有正在审核中的策略申请记录");
        }
        WarnStrategyCheck warnStrategyCheck = new WarnStrategyCheck();
        warnStrategyCheck.setCheckStatus(0);
        warnStrategyCheck.setApplicationTime(DateUtil.format(new Date(), format));
        warnStrategyCheck.setEnterpriseName(request.getEnterpriseName());
        warnStrategyCheck.setHighReport(request.getHighReport());
        warnStrategyCheck.setLowReport(request.getLowReport());
        warnStrategyCheck.setRuleId(request.getId());
        warnStrategyCheck.setRuleJsonData(com.alibaba.fastjson.JSONObject.toJSONString(request));
        warnStrategyCheck.setRuleName(request.getRuleName());
        warnStrategyCheck.setStrategyObjValues(request.getStrategyObjValues());
        warnStrategyCheck.setSubmitPersonCode(ApplicationUtils.getWorkingUser().getUsername());
        warnStrategyCheck.setSubmitPersonName(ApplicationUtils.getWorkingUser().getName());
        warnStrategyCheck.setSubmitPersonPhone(ApplicationUtils.getWorkingUser().getPhone());
        warnStrategyCheck.setStrategyEquipment(0);
        warnStrategyCheck.setSpId(spId);
        warnStrategyCheck.setStrategyObj(request.getStrategyObj());
        warnStrategyCheckMapper.insert(warnStrategyCheck);
    }

    public void checkRule(SaveWarnStrategyRequest request) {

        String lowWxPhones = request.getLowWxPhones();
        String highWxPhones = request.getHighWxPhones();
        if (!StringUtils.isEmpty(lowWxPhones)) {
            if (lowWxPhones.contains(split)) {
                checkPhone(lowWxPhones, null);
            } else {
                throw new BizException("输入格式错误");
            }
        }
        if (!StringUtils.isEmpty(highWxPhones)
                && highWxPhones.contains(split)) {
            if (highWxPhones.contains(split)) {
                checkPhone(highWxPhones, null);
            } else {
                throw new BizException("手机号格式错误");
            }
        }

        if ((!StringUtils.isEmpty(request.getLowReport()) && !NumberUtil.isNumber(request.getLowReport())) ||
                (!StringUtils.isEmpty(request.getHighReport()) && !NumberUtil.isNumber(request.getHighReport()))) {
            throw new BizException("报警值2报警值1值请输入数字");
        }
        if ((!StringUtils.isEmpty(request.getLowReport()) && (Integer.parseInt(request.getLowReport()) <= 0
                || Integer.parseInt(request.getLowReport()) >= 100))
                || (!StringUtils.isEmpty(request.getHighReport()) && (Integer.parseInt(request.getHighReport()) > 100
                || Integer.parseInt(request.getHighReport()) <= 0))) {
            throw new BizException("请输入正确的报警值2报警值1值范围");
        }
        Integer low = null;
        Integer high = null;
        if (!StringUtils.isEmpty(request.getLowReport()) && !StringUtils.isEmpty(request.getHighReport())) {
            low = Integer.parseInt(request.getLowReport());
            high = Integer.parseInt(request.getHighReport());
            if (low != null && high != null && low >= high)
                throw new BizException("报警值2值应高于报警值1值");
        }
        if (low != null && low == 0) throw new BizException("报警值1值不能为0");
        if (high != null && high == 0) throw new BizException("报警值2值不能为0");
        //对于细节字段校验
        if (!StringUtils.isEmpty(request.getLowReport())) {
            if (request.getLowType() == null ||
                    (request.getLowReportInterval() == null && request.getLowSendInterval() == null
                            && request.getLowWxInterval() == null && request.getLowCallInterval() == null)) {
                throw new BizException("报警值1详细规则请填写完整");
            }
        } else {
            if (request.getLowType() != null && request.getLowType() != -1) throw new BizException("报警值1详细规则请填写完整");
        }
        if (!StringUtils.isEmpty(request.getHighReport())) {
            if (request.getHighType() == null ||
                    (request.getHighReportInterval() == null && request.getHighSendInterval() == null
                            && request.getHighWxInterval() == null && request.getHighCallInterval() == null)) {
                throw new BizException("报警值2详细规则请填写完整");
            }
        } else {
            if (request.getHighType() != null && request.getHighType() != -1) throw new BizException("报警值2详细规则请填写完整");
        }
        List<WarnStrategyExtRequest> extData = request.getExtData();
        //1本地消息中心 2 短信推送 3 微信模版消息 4机器人外呼
        List<Integer> integers = new ArrayList<>();
        integers.add(2);
        integers.add(4);
        Set<Integer> getPushTypes = PushTypeEnum.getPushTypes(integers, 0);
        if ((!StringUtils.isEmpty(request.getLowReport()) && extData.size() <= 0
                && (getPushTypes.contains(request.getLowType()))) ||
                (!StringUtils.isEmpty(request.getHighReport()) && extData.size() <= 0 && (
                        getPushTypes.contains(request.getHighType())))) {
            throw new BizException("请至少填写一个实际发送规则");
        }
        Map<Integer, List<WarnStrategyExtRequest>> collect = extData.stream()
                .collect(Collectors.groupingBy(WarnStrategyExtRequest::getPushType,
                        Collectors.toList()));
        collect.forEach((integer, warnStrategyExtRequests) -> {
            Set<Integer> types = null;
            if (integer == 1) types = PushTypeEnum.getPushTypes(null, 2);
            if (integer == 2) types = PushTypeEnum.getPushTypes(null, 4);
            checkWarnStrategyExt(warnStrategyExtRequests, types, request, integer);
        });
    }

    public void checkWarnStrategyExt(List<WarnStrategyExtRequest> extData, Set<Integer> getPushTypes
            , SaveWarnStrategyRequest request, int type) {
        log.info("checkWarnStrategyExt-type:{}", type);
        extData.forEach(warnStrategyExtRequest -> {
//            String phones = type == 1 ? warnStrategyExtRequest.getSendPhones() : warnStrategyExtRequest.getCallPhones();
            //
            String phones = warnStrategyExtRequest.getCallPhones();
            if (!StringUtils.isEmpty(phones)
                    && phones.contains(split)) {
                if (phones.contains(split)) {
                    checkPhone(phones, type == 1 ? null : 0);
                } else {
                    throw new BizException("传入数据格式错误");
                }
            }
        });
        for (int i = 0; i < extData.size(); i++) {
            extData.get(i).setSort(i);
        }
        Map<Integer, List<WarnStrategyExtRequest>> collect = extData.stream()
                .collect(Collectors.groupingBy(WarnStrategyExtRequest::getType,
                        Collectors.toList()));

        if (collect.size() > 0) {
            if ((getPushTypes.contains(request.getLowType())) &&
                    (getPushTypes.contains(request.getHighType()))
                    && collect.size() < 2
                    ) {
                throw new BizException("请补充完整推送对象规则");
            }

        } else {
            if (getPushTypes.contains(request.getLowType())
                    || getPushTypes.contains(request.getHighType())) {
                throw new BizException("请补充完整推送对象规则");
            }
        }
        collect.forEach((integer, extDataType) -> {
            if (!CollectionUtil.isEmpty(extDataType)) {
                if (extDataType.size() > 10) throw new BizException("最多添加10条发送对象策略");
                int value = 0;
                extDataType.sort((o1, o2) -> {
                    return o1.getSort() - o2.getSort();
                });
                int first = 0;
                for (WarnStrategyExtRequest warnStrategyExtRequest : extDataType) {
                    first = first + 1;
                    Integer reportNumberEnd = warnStrategyExtRequest.getReportNumberEnd();
                    Integer reportNumberStart = warnStrategyExtRequest.getReportNumberStart();
                    if (reportNumberEnd == null || reportNumberStart == null) {
                        throw new BizException("请正确填写发送次数");
                    } else if (reportNumberEnd < reportNumberStart) {
                        throw new BizException("开始次数要小于等于结束次数");
                    }
                    if (warnStrategyExtRequest.getPushLevel() == null &&
                            StringUtils.isEmpty(warnStrategyExtRequest.getPushStaffs())
                            && StringUtils.isEmpty(warnStrategyExtRequest.getCallPhones())
                            )
                        throw new BizException("请选择发送级别或企业员工以及额外手机号信息");
                    if (reportNumberStart <= value) {
                        throw new BizException("新规则的开始次数要大于上个规则的结束次数");
                    }
                    value = reportNumberEnd;
                    log.debug("checkRule", reportNumberEnd, reportNumberStart);
                    if (reportNumberEnd > 50 || reportNumberStart > 50) {
                        throw new BizException("发送次数最大限额50次");
                    }
                    if ((extDataType.size() == 1 || first == 1) && reportNumberStart > 1) {
                        throw new BizException("次数请从1开始");
                    }


                }
            }
        });
    }

    public void checkPhone(String highWxPhones, Integer type) {
        log.info("checkPhone-params:{},{}", highWxPhones, type);
        String[] split = highWxPhones.split(WarnStrategyServiceImpl.split);
        for (String s : split) {
            boolean isMatch = Pattern.matches(phoneRegex, s);
            boolean landlineMatch = false;
            landlineMatch = Pattern.matches(landlineRegex, s);
            log.info("checkPhone-isMatch:{},{}", isMatch, s);
            log.info("checkPhone-landlineMatch:{},{}", landlineMatch, s);
            if (!isMatch && !landlineMatch){
                throw new BizException("联系方式格式存在错误");
            }
        }
    }

    private void setStrategyCache(WarnStrategy warn) {
        Set<Object> set = new HashSet<>();
        Set<Object> cacheSet = redisCache.getCacheSet(Constants.WARNING_EQUIPMENT + ":" + "strategy");
        if (!CollectionUtil.isEmpty(cacheSet)) {
            set = cacheSet;
        }
        set.add(warn.getId());
    }
}
